[bits 32]

%define ERROR_CODE nop
%define ZERO push dword 0

extern _IDTTable
extern _SyscallTable

section .data
global _IntrEntryTable
_IntrEntryTable:

%macro VECTOR 2
section .text
Intr%1Entry:
    %2
    
    cld
    push ds
    push es
    push fs
    push gs
    pushad

    push dword %1
    call [_IDTTable + %1 * 4]
    jmp IntrExit

section .data
    dd Intr%1Entry

%endmacro

%macro VECTOR2 2
section .text
Intr%1Entry:
    %2
    push ds
    push es
    push fs
    push gs
    pushad

    push dword %1
    call [_IDTTable + %1 * 4]

    mov al,0x20
    out 0x20,al

    jmp IntrExit

section .data
    dd Intr%1Entry

%endmacro

section .text
global IntrExit
IntrExit:
   add esp,4
   popad
   pop gs
   pop fs
   pop es
   pop ds
   add esp,4
   iretd

VECTOR 0x00,ZERO
VECTOR 0x01,ZERO
VECTOR 0x02,ZERO
VECTOR 0x03,ZERO
VECTOR 0x04,ZERO
VECTOR 0x05,ZERO
VECTOR 0x06,ZERO
VECTOR 0x07,ZERO
VECTOR 0x08,ZERO
VECTOR 0x09,ZERO
VECTOR 0x0a,ERROR_CODE
VECTOR 0x0b,ERROR_CODE
VECTOR 0x0c,ZERO
VECTOR 0x0d,ERROR_CODE
VECTOR 0x0e,ERROR_CODE
VECTOR 0x0f,ZERO
VECTOR 0x10,ZERO
VECTOR 0x11,ERROR_CODE
VECTOR 0x12,ZERO
VECTOR 0x13,ZERO
VECTOR 0x14,ZERO
VECTOR 0x15,ZERO
VECTOR 0x16,ZERO
VECTOR 0x17,ZERO
VECTOR 0x18,ERROR_CODE
VECTOR 0x19,ZERO
VECTOR 0x1a,ERROR_CODE
VECTOR 0x1b,ERROR_CODE
VECTOR 0x1c,ZERO
VECTOR 0x1d,ERROR_CODE
VECTOR 0x1e,ERROR_CODE
VECTOR 0x1f,ZERO
VECTOR2 0x20,ZERO    ;clock interrupt 
VECTOR2 0x21,ZERO	;keyboard interrupt
VECTOR2 0x22,ZERO	;
VECTOR2 0x23,ZERO	;com2 entry
VECTOR2 0x24,ZERO	;com1 entry
VECTOR2 0x25,ZERO	;parallel port2 entry
VECTOR2 0x26,ZERO	;floppy entry
VECTOR2 0x27,ZERO	;parallel port1 entry
VECTOR 0x28,ZERO	;real clock interrupt
VECTOR 0x29,ZERO	;redirected
VECTOR 0x2a,ZERO	;reserved
VECTOR 0x2b,ZERO	;reserved
VECTOR 0x2c,ZERO	;ps/2 mouse
VECTOR 0x2d,ZERO	;fpu exception
VECTOR 0x2e,ZERO	;harddisk
VECTOR 0x2f,ZERO	;reserved

VECTOR 0x30,ZERO
VECTOR 0x31,ZERO
VECTOR 0x32,ZERO
VECTOR 0x33,ZERO
VECTOR 0x34,ZERO
VECTOR 0x35,ZERO
VECTOR 0x36,ZERO
VECTOR 0x37,ZERO
VECTOR 0x38,ZERO
VECTOR 0x39,ZERO
VECTOR 0x3a,ZERO
VECTOR 0x3b,ZERO
VECTOR 0x3c,ZERO
VECTOR 0x3d,ZERO
VECTOR 0x3e,ZERO
VECTOR 0x3f,ZERO
VECTOR 0x40,ZERO
VECTOR 0x41,ZERO
VECTOR 0x42,ZERO
VECTOR 0x43,ZERO
VECTOR 0x44,ZERO
VECTOR 0x45,ZERO
VECTOR 0x46,ZERO
VECTOR 0x47,ZERO
VECTOR 0x48,ZERO
VECTOR 0x49,ZERO
VECTOR 0x4a,ZERO
VECTOR 0x4b,ZERO
VECTOR 0x4c,ZERO
VECTOR 0x4d,ZERO
VECTOR 0x4e,ZERO
VECTOR 0x4f,ZERO
VECTOR 0x50,ZERO
VECTOR 0x51,ZERO
VECTOR 0x52,ZERO
VECTOR 0x53,ZERO
VECTOR 0x54,ZERO
VECTOR 0x55,ZERO
VECTOR 0x56,ZERO
VECTOR 0x57,ZERO
VECTOR 0x58,ZERO
VECTOR 0x59,ZERO
VECTOR 0x5a,ZERO
VECTOR 0x5b,ZERO
VECTOR 0x5c,ZERO
VECTOR 0x5d,ZERO
VECTOR 0x5e,ZERO
VECTOR 0x5f,ZERO
VECTOR 0x60,ZERO
VECTOR 0x61,ZERO
VECTOR 0x62,ZERO
VECTOR 0x63,ZERO
VECTOR 0x64,ZERO
VECTOR 0x65,ZERO
VECTOR 0x66,ZERO
VECTOR 0x67,ZERO
VECTOR 0x68,ZERO
VECTOR 0x69,ZERO
VECTOR 0x6a,ZERO
VECTOR 0x6b,ZERO
VECTOR 0x6c,ZERO
VECTOR 0x6d,ZERO
VECTOR 0x6e,ZERO
VECTOR 0x6f,ZERO
VECTOR 0x70,ZERO
VECTOR 0x71,ZERO
VECTOR 0x72,ZERO
VECTOR 0x73,ZERO
VECTOR 0x74,ZERO
VECTOR 0x75,ZERO
VECTOR 0x76,ZERO
VECTOR 0x77,ZERO
VECTOR 0x78,ZERO
VECTOR 0x79,ZERO
VECTOR 0x7a,ZERO
VECTOR 0x7b,ZERO
VECTOR 0x7c,ZERO
VECTOR 0x7d,ZERO
VECTOR 0x7e,ZERO
VECTOR 0x7f,ZERO

;;;;;;;;;;;;;;;;   0x80 interrupt   ;;;;;;;;;;;;;;;;
section .text
global _SyscallHandler
_SyscallHandler:
;save context
   push dword 0			; format stack(to meet the intr_exit stack require)

   push ds
   push es
   push fs
   push gs
   pushad			    ; PUSHAD: EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI 
				 
   push dword 0x80		; format stack(to meet the intr_exit stack require)

   cmp eax, 100
   ja IntrExit

;push argc of syscall
   push edx			    ; the 3rd argc
   push ecx			    ; the 2th argc
   push ebx			    ; the 1st argc

;call handler of sub_function
   call [_SyscallTable + eax*4]	    ; index in table by eax
   add esp, 12			    ; balance stack to skip three argc

;save return val(eax) to eax_stack_memory
   mov [esp + 8*4], eax	
   jmp IntrExit		    ; intr_exit to recover context
